package com.iwop.moto.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.iwop.moto.comm.Comm;
import com.iwop.moto.model.*;
import com.iwop.moto.service.*;
import com.iwop.moto.utils.PushNoticeUtil;
import com.iwop.moto.utils.alipay.AliPayComm;
import com.iwop.moto.utils.http.SessionUtils;
import com.iwop.moto.utils.stringUtil.BigDecimalUtil;
import com.iwop.moto.utils.stringUtil.JsonUtils;
import com.iwop.moto.utils.stringUtil.ObjectId;
import com.iwop.moto.utils.stringUtil.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

/**
 * Created by mobom on 2016/12/30.
 */

@Service
public class PayServiceImpl implements PayService{

    @Autowired
    private FErrorLogService fErrorLogService;
    @Autowired
    private MPaymentService mPaymentService;

    @Autowired
    FOrderServiceService fOrderServiceService;

    @Autowired
    UserService userService;

    @Autowired
    private StoreService storeService;

    @Autowired
    private MCouponService mCouponService;

    @Autowired
    private MOrderPurchaseService mOrderPurchaseService;

    @Autowired
    private PromotionService promotionService;

    @Autowired
    MBrokerageService mBrokerageService;

    @Autowired
    MGPOrderService mgpOrderService;

    @Override
    @Transactional
    public String addAliBack(Map<String, String> params, boolean resultBl, Map<String, String> body) {
        String responseMsg = "failure"; //支付宝响应消息
        System.out.println("支付宝回调参数:\n" + params.toString());//打印本次请求日志，开发者自行决定是否需要
            if (!params.get("app_id").equals(AliPayComm.APP_ID)) {//非法请求:APP_ID 不匹配
                ErrorLog(null, "/api/alipay/gateway:APP_ID不匹配", JsonUtils.toJsonString(params));
                return responseMsg;
            }
            if (resultBl) {//2.验证签名
                MPayment payment = new MPayment();
                //验证支付宝是否成功收到这笔订单
                if (params.get("trade_status").equals("TRADE_SUCCESS")) {
                    payment.setPayStatus("1");//1:成功 2 失效 - TRADE_SUCCESS
                } else {
                    payment.setPayStatus("2");//1:成功 2 失效 - TRADE_CLOSED/TRADE_FINISHED
                    return responseMsg;
                }

                payment.setPayId(ObjectId.UUID());
                payment.setBuyerUserId(body.get("user_id").toString());//开摩邦用户id(买家/付款方)
                String coupon_id = "";
                boolean coupon_id1 = body.containsKey("coupon_id");
                if (coupon_id1) {
                    coupon_id = body.get("coupon_id");
                }
                String sid = "";
                if (body.containsKey("sid")) {
                    sid = body.get("sid");
                }
                SuperRecordModel sm = new SuperRecordModel();
                if ((!StringUtils.isEmpty(coupon_id)) || (!StringUtils.isEmpty(sid))) {
                    sm.put("user_id", body.get("user_id").toString());
                    sm.put("coupon_id", coupon_id);
                    sm.put("sid", sid);
                    sm.put("status_flag", 2);//1：未使用，2：已使用
                    sm.put("status_time", new Date());
                    updateCouponStatus(sm);
                }
                payment.setMchType("ALIPAY");
                payment.setPayBuyerId(params.get("buyer_id"));//支付用户Id
                payment.setPaySellerId(params.get("seller_id"));//
                payment.setMchId(AliPayComm.APP_ID);
                payment.setPayTradeNo(params.get("trade_no"));
                boolean countBl = mPaymentService.findByPayTradeNoCount(payment);
                if (countBl == false) {/** 判断支付宝的回调订单号是否处理过 避免重复金额错误 **/
                    ErrorLog(null, "/api/alipay/gateway:支付宝重复订单回调", JsonUtils.toJsonString(params));
                    return responseMsg;
                }
                //获取佣金
                String brokerage1 = body.get("brokerage");//佣金
                double parseBrokerage = 0;
                if (!StringUtils.isEmpty(brokerage1)) {
                    parseBrokerage = Double.parseDouble(brokerage1);
                }
                payment.setBrokerage(parseBrokerage);

                //订单类型
                payment.setPayType(body.get("order_type") == null ? null : body.get("order_type").toString());

                //优惠后实际付款到蚂蚁金服的金额
                String total_amount = params.get("total_amount");
                Double payMoney = Double.valueOf(total_amount);
                payment.setPayActualMoney(payMoney);

                //设置交易金额
                payMoney = BigDecimalUtil.getAdd(parseBrokerage, payMoney);
                payment.setPayMoney(payMoney);

                //交易时间和备注
                payment.setPayTime(new Date());// 交易时间
                payment.setPayDescribe(params.get("subject") == null ? "" : params.get("subject"));

                // 如果是服务订单的业务处理逻辑
                if (body.get("order_type").equals("Service")) {
                    if (!StringUtils.isEmpty(coupon_id)) {
                        SuperRecordModel superRecordModel = new SuperRecordModel();
                        superRecordModel.put("sid", coupon_id);
                        SuperRecordModel coupon = mCouponService.getCouponById(superRecordModel);
                        payment.setCouponId(coupon_id);
                        BigDecimal money = (BigDecimal) coupon.get("money");
                        double cmoney = Double.parseDouble(money.doubleValue() + "");

                        // 付款金额+抵用券金额
                        payment.setPayMoney(BigDecimalUtil.getAdd(payMoney, cmoney));
                        //平台服务费
                        double brokerage = BigDecimalUtil.getMultiply(payment.getPayMoney(), Comm.BROKERAGE);
                        payment.setPayFee(brokerage);
                        //交易金额 = 付款金 + 优惠券金 + 佣金
                        payment.setPayMoney(BigDecimalUtil.getSubtract(payment.getPayMoney(), brokerage));

                    } else {
                        double brokerage = BigDecimalUtil.getMultiply(payMoney, Comm.BROKERAGE);
                        payment.setPayFee(brokerage);
                        payment.setPayMoney(BigDecimalUtil.getSubtract(payment.getPayMoney(), brokerage)); // 付款金额+抵用券金额 扣钱金额
                    }
                    User storeUser = judgeOrderType(body,payment);
                    payment.setOriginalTmoney(storeUser.getRmoney());//用户操作前金额
                    storeUser.setRmoney(BigDecimalUtil.getAdd(storeUser.getRmoney(), payment.getPayMoney()));//用户操作成功后金额
                    payment.setModifyTmoney(storeUser.getRmoney());//用户修改后金额
                    userService.updateUserRmoneyBySid(storeUser);

                    if (parseBrokerage > 0) {
                        User userBySid = userService.getUserBySid(payment.getBuyerUserId());
                        if (userBySid.getRedPacket() > parseBrokerage) {
                            userBySid.setRedPacket(BigDecimalUtil.getSubtract(userBySid.getRedPacket(), parseBrokerage));
                        } else {
                            userBySid.setRedPacket(0);
                        }
                        userService.updateRedPacketBySid(userBySid);
                    }

                    payment.setSellerUserId(storeUser.getSid());//开摩邦用户id(卖家/收款方)
                    PushNoticeUtil.sendPersonNotice("您有一笔订单已付款成功!", "store", storeUser.getSid());
                } else if (body.get("order_type").equals("Topup")) {/**  用户充值接口 **/
                    payment.setOutTradeNo(params.get("out_trade_no"));
                    payment.setPayTime(new Date());
                    payment.setSellerUserId(payment.getBuyerUserId());//开摩邦用户id(卖家/收款方) 注:
                    User user = userService.getUserBySid(payment.getBuyerUserId());
                    payment.setOriginalTmoney(user.getRmoney());//用户操作前金额
                    user.setRmoney(user.getRmoney() + payment.getPayMoney());//用户操作成功后金额
                    payment.setModifyTmoney(user.getRmoney());//用户修改后金额
                    userService.updateUserRmoneyBySid(user);
                } else {
                    ErrorLog(null, "/api/alipay/gateway:交易类型不存在", JsonUtils.toJsonString(params));
                }
                mPaymentService.insert(payment);
                Double payFee = 0d;
                if (payment.getPayFee()!=null){
                    payFee = payment.getPayFee();
                }
                Double payMoney1 = payment.getPayMoney();
                double money = BigDecimalUtil.getAdd(payFee.doubleValue(), payMoney1.doubleValue());
                addBrokerage(body.get("user_id").toString(), payment.getOutTradeNo(), money);
               // userService.userProceeds(body.get("user_id").toString(), payment.getOutTradeNo(), money);

                responseMsg = "success";//success
            } else {
                ErrorLog(null, "/api/alipay/gateway:签名验证失败", JsonUtils.toJsonString(params));
            }
        return responseMsg;
    }

    /**
     * 判断是推送付款订单，采购订单
     */
    private User judgeOrderType(Map attach, MPayment payment) {
        User storeUser = new User();
        String orderType = (String) attach.get("ctype");
        String out_trade_no = (String) attach.get("out_trade_no");
        if(out_trade_no.contains("Ho")){
            MGPOrder mgpOrder = mgpOrderService.findGPOrderByPayOutTradeNo(out_trade_no);
            payment.setOutTradeNo(mgpOrder.getOrderNo());
            payment.setPayType("TRANSFER");
            mgpOrder.setStatusFlag("1");
            payment.setContent(mgpOrder.getContent());
            mgpOrderService.updateMGPOrder(mgpOrder);
            SuperRecordModel store = storeService.getStoreBySid(mgpOrder.getStoreId());
            storeUser = userService.getUserBySid(store.get("user_id").toString());
        }else {
            if (orderType.equals("user")) {
                SuperRecordModel service = new SuperRecordModel();
                service = fOrderServiceService.getStoreOrderByOrderNo(out_trade_no);
                payment.setOutTradeNo(service.getString("orderno"));
                service.put("pushstatus", "1");//支付成功
                fOrderServiceService.updateStoreOrderStatus(service);
                SuperRecordModel store = storeService.getStoreBySid(service.get("store_id").toString());
                storeUser = userService.getUserBySid(store.get("user_id").toString());
            } else {
                MOrderPurchase mOrderPurchase = mOrderPurchaseService.findOneByPayOrderNo(out_trade_no);
                payment.setOutTradeNo(mOrderPurchase.getSid());
                mOrderPurchase.setStatus(1);
                mOrderPurchaseService.updateOrderPurchase(mOrderPurchase);
                SuperRecordModel store = storeService.getStoreBySid(mOrderPurchase.getSellerStoreId());
                storeUser = userService.getUserBySid(store.get("user_id").toString());
            }
        }
        return storeUser;
    }

    public void updateCouponStatus(SuperRecordModel superRecordModel1) {
        try {
            mCouponService.updateUserCouponStatusBySid(superRecordModel1);
        } catch (Exception e) {
            e.printStackTrace();
            ErrorLog(e, "method:updateCouponStatus系统异常", JsonUtils.toJsonString(superRecordModel1));
        }
    }

    /**
     * 添加佣金
     */
    public void addBrokerage(String user_id, String order_id, double moneys) {
        if (moneys >= 5) {
            String keyName = user_id + "_new";
            String valueFromSession = (String) SessionUtils.getValueFromSession(keyName);
            if (!StringUtils.isEmpty(valueFromSession)) {
                if (valueFromSession.equals("new")) {
                    String hostUserInfo = promotionService.findHostUserById(user_id);
                    int count = promotionService.countFromUserByHostId(hostUserInfo);
                    double money = getBrokerage(count);
                    if (!StringUtils.isEmpty(hostUserInfo)) {
                        User userBySid = userService.getUserBySid(hostUserInfo);
                        if (userBySid != null) {
                            MBrokerage mBrokerage = new MBrokerage();
                            mBrokerage.setSid(ObjectId.UUID());
                            mBrokerage.setSellerUserId(userBySid.getSid());
                            mBrokerage.setBuyerUserId(user_id);
                            mBrokerage.setOriginalTmoney(userBySid.getRedPacket());
                            double modifyTmoney = userBySid.getRedPacket() + money;
                            mBrokerage.setModifyTmoney(modifyTmoney);
                            mBrokerage.setPayMoney(money);
                            mBrokerage.setPayStatus("1");
                            mBrokerage.setPayType("ALIPAY");
                            mBrokerage.setPayTime(new Date());
                            mBrokerage.setOutTradeNo(order_id);
                            mBrokerageService.insert(mBrokerage);
                            userBySid.setRedPacket(modifyTmoney);
                            userService.updateRedPacketBySid(userBySid);
                            SessionUtils.setKeyValueString(keyName, "old");
                            User userBySid1 = userService.getUserBySid(user_id);
                            userBySid1.setNewUser("old");
                            userService.updateRedPacketBySid(userBySid1);
                        }
                    }
                }
            }
        }
    }

    private double getBrokerage(int people) {
        if (people < 19) {
            return 4;
        } else if (people < 99) {
            return 5;
        } else {
            return 6;
        }
    }

    @Override
    public String addWinXinBack(String input) {
        return null;
    }

    @Override
    @Transactional
    public String addAliH5PayBack(Map<String,String> params) throws AlipayApiException, IOException {
        String responseMsg = "failure"; //支付宝响应消息
        if (!params.get("app_id").equals(AliPayComm.APP_ID)) {//非法请求:APP_ID 不匹配
            ErrorLog(null, "/api/alipay/gateway:APP_ID不匹配", JsonUtils.toJsonString(params));
            return responseMsg;
        }
        boolean resultBl = AlipaySignature.rsaCheckV1(params, AliPayComm.ALIPAY_PUBLIC_KEY,
                AliPayComm.SIGN_CHARSET);
        if(resultBl){
            String buyer_logon_id = params.get("buyer_logon_id");//付款方id
            String out_trade_no = params.get("out_trade_no");
            MGPOrder mg = mgpOrderService.findGPOrderByPayOutTradeNo(out_trade_no);
            String money = params.get("total_amount");
            double payMoney = Double.parseDouble(money);
            MPayment payment = new MPayment();
            payment.setPayId(ObjectId.UUID());
            payment.setBuyerUserId(buyer_logon_id);//开摩邦用户id(买家/付款方)
            payment.setMchId(AliPayComm.APP_ID);
            payment.setOutTradeNo(params.get("out_trade_no"));
            payment.setPayTradeNo(params.get("trade_no"));
            payment.setPayActualMoney(payMoney);
            payment.setPayType("TRANSFER");
            payment.setMchType("ALIPAY");
            payment.setPayTime(new Date());// 交易时间
            payment.setPayDescribe(params.get("subject") == null ? "" : params.get("subject"));
            double brokerage = BigDecimalUtil.getMultiply(payMoney, Comm.BROKERAGE);//平台服务费
            payment.setPayFee(brokerage);//服务费
            double subtract = BigDecimalUtil.getSubtract(payMoney, brokerage);
            payment.setPayMoney(subtract);
            if (params.get("trade_status").equals("TRADE_SUCCESS")) {
                payment.setPayStatus("1");//1:成功 2 失效 - TRADE_SUCCESS
            } else {
                payment.setPayStatus("2");//1:成功 2 失效 - TRADE_CLOSED/TRADE_FINISHED
                return responseMsg;
            }

            boolean countBl = mPaymentService.findByPayTradeNoCount(payment);
            if (countBl == false) {/** 判断支付宝的回调订单号是否处理过 避免重复金额错误 **/
                ErrorLog(null, "/api/alipay/gateway:支付宝重复订单回调", JsonUtils.toJsonString(params));
                return responseMsg;
            }
            SuperRecordModel storeBySid = storeService.getStoreBySid(mg.getStoreId());
            String userId = storeBySid.getString("user_id");
            User user = userService.getUserBySid(userId);
            Double rmoney = user.getRmoney();
            payment.setOriginalTmoney(rmoney);
            double addMoney = BigDecimalUtil.getAdd(rmoney, payment.getPayMoney());
            payment.setModifyTmoney(addMoney);//用户修改后金额
            user.setRmoney(addMoney);
            userService.updateUserRmoneyBySid(user);
            MGPOrder mgpOrder = mgpOrderService.findOneBySid(out_trade_no);
            payment.setContent(mgpOrder.getContent());
            mgpOrder.setUserId(buyer_logon_id);
            mgpOrder.setStatusFlag("1");
            mgpOrder.setStatusTime(new Date());
            mgpOrderService.updateMGPOrder(mgpOrder);
            payment.setSellerUserId(user.getSid());
            mPaymentService.insert(payment);
            return "SUCCESS";
        }else {
            ErrorLog(null, "/api/alipay/gateway:签名验证失败", JsonUtils.toJsonString(params));
            return responseMsg;
        }
    }

    public void ErrorLog(Exception e,String ... params){
        FErrorLog errorLog = new FErrorLog();
        errorLog.setErrName(params.length==0?null:params[0]);
        errorLog.setErrData(params.length<2?null:params[1]);
        if(e!=null){
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            errorLog.setErrContent(sw.toString());
        }
        fErrorLogService.insert(errorLog);
    }
}
